export {
    dragElement,
    sendTextToClipboard,
    hideEmptyElement,
    removeEndChar
}

// 拖拽元素
function dragElement(
  elementToDrag: HTMLElement,
  dragHandler: HTMLElement
): void {
  /*
  参数1必选：要移动的元素
  参数2必选：触发拖拽行为的元素
  
  返回值：无
  */
  let startX = 0,
    startY = 0,
    moveDistanceX = 0,
    moveDistanceY = 0;

  // 监听鼠标按下事件，
  dragHandler.addEventListener("mousedown", startDragging);

  // 鼠标按下拖拽
  function startDragging(e: MouseEvent): void {
    e.preventDefault();
    // console.log('鼠标按下，开始拖动');

    // 记录鼠标相对于窗口的初始位置
    startX = e.clientX;
    startY = e.clientY;

    // 监听鼠标移动和释放事件
    document.addEventListener("mousemove", dragging);
    document.addEventListener("mouseup", stopDragging);
  }

  // 元素拖动
  function dragging(e: MouseEvent): void {
    // 阻止默认事件
    e.preventDefault();
    // console.log('鼠标拖动');
    // 计算鼠标的移动距离
    moveDistanceX = startX - e.clientX;
    moveDistanceY = startY - e.clientY;
    // 存储鼠标的新位置
    startX = e.clientX;
    startY = e.clientY;
    // 更新元素位置
    elementToDrag.style.left = elementToDrag.offsetLeft - moveDistanceX + "px";
    elementToDrag.style.top = elementToDrag.offsetTop - moveDistanceY + "px";
  }

  // 结束拖动元素，清理监听器
  function stopDragging(): void {
    // console.log('鼠标弹起，拖动结束');
    document.removeEventListener("mouseup", stopDragging);
    document.removeEventListener("mousemove", dragging);
  }
}

// 发送文本到剪贴板
function sendTextToClipboard(text: string): Promise<void> {
  /*
  参数1必选：要发送到剪贴板的文本

  返回值：void
  返回：Promise，复制成功则解决，复制失败则拒绝
  */
  return new Promise((resolve, reject) => {
    // 检查浏览器环境是否支持clipboard api，如不支持，则使用execCommand
    if (!navigator.clipboard || !navigator.clipboard.writeText) {
      // 创建一个文本域元素，存储要复制的文本
      let textArea = document.createElement("textarea");
      textArea.value = text;
      // 将文本域元素扔到页面之外
      textArea.style.position = "fixed";
      textArea.style.top = "-10rem";
      textArea.style.left = "-10rem";
      textArea.style.width = "2rem";
      textArea.style.height = "2rem";
      textArea.style.padding = "0";
      textArea.style.border = "none";
      textArea.style.outline = "none";
      textArea.style.boxShadow = "none";
      textArea.style.background = "transparent";
      // 将文本域添加到body下，并选中文字
      document.body.appendChild(textArea);
      textArea.select();

      try {
        // 尝试复制选中文字，保存复制结果，处理Promise
        let copy_successful = document.execCommand("copy");
        if (copy_successful) {
          // console.log('已复制文本到剪贴板');
          resolve();
        } else {
          console.error("无法复制文本");
          reject(new Error("无法复制文本"));
        }
      } catch (err) {
        console.error("无法复制文本", err);
        reject(err);
      } finally {
        // 无论是否复制成功，移除文本域元素
        document.body.removeChild(textArea);
      }
    } else {
      // 若支持clipboard api则使用它进行复制
      navigator.clipboard
        .writeText(text)
        .then(() => {
          // console.log('已复制文本到剪贴板');
          resolve();
        })
        .catch((err) => {
          console.error("无法复制文本：", err);
          reject(err);
        });
    }
  });
}

// 删除字符串末尾的指定字符
function removeEndChar(parentString: string, removeChar: string): string {
  /*
  参数1必选：要进行移除字符的字符串
  参数2必选：要从字符串中移除的字符

  返回值：字符串
  */
  if (parentString.endsWith(removeChar)) {
    return parentString.slice(0, -removeChar.length);
  }

  return parentString;
}

// 判断指定元素内容是否为空，如为空则隐藏指定元素
function hideEmptyElement(
  sourceElement: HTMLElement | null,
  targetElement: HTMLElement
): void {
  /*
  参数1必选：要判断的元素
  参数2必选：要隐藏的元素，不能为null

  返回值：无
  */
  let haveText = hasText(sourceElement);

  // 判断是否有文本及元素是否存在，如果没有则隐藏元素，有则使用默认样式
  if (!haveText) {
    targetElement.style.display = "none";
  } else {
    targetElement.style.display = "";
  }
}

// 检查指定元素及所有子元素中是否有文本内容
function hasText(element: HTMLElement | null): boolean {
  // 元素不存在直接返回false
  if (!element) return false;

  // 检查元素内的文本内容是否为空，不为空则返回true
  if (element.textContent?.trim()) {
    return true;
  }

  // 遍历查找子节点的文本内容
  for (let child of element.childNodes) {
    // 如果是文本节点，检查内容是否为空
    if (
      child.nodeType === Node.TEXT_NODE &&
      (child as Text).textContent?.trim()
    ) {
      return true;
      // 如果是元素节点，递归检查其子元素内容是否为空
    } else if (
      child.nodeType === Node.ELEMENT_NODE &&
      hasText(child as HTMLElement)
    ) {
      return true;
    }
  }

  // 若无内容，则返回false
  return false;
}
